package com.bzsg.rightsManagementSystem.controller

import com.alibaba.fastjson.JSON
import com.bzsg.rightsManagementSystem.pojo.PersonUser
import com.bzsg.rightsManagementSystem.service.RoleService
import com.bzsg.rightsManagementSystem.service.UserService
import com.bzsg.rightsManagementSystem.util.result.ErrorType
import com.bzsg.rightsManagementSystem.util.result.RequestResult
import com.bzsg.rightsManagementSystem.util.result.ResultUtil
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.*
import java.util.*


@Controller
class UserController {
    private val logger = LoggerFactory.getLogger(this.javaClass)

    @Autowired
    private lateinit var userService: UserService


    @Autowired
    private lateinit var roleService: RoleService

    @Autowired
    private lateinit var passwordEncode: BCryptPasswordEncoder

    @PostMapping(value = ["api/addUser"])
    @ResponseBody
    fun addUser(@RequestBody newUser: PersonUser, @RequestParam userName: String): RequestResult<*> {
        return try {
            if (userService.selectUserByAccount(newUser.account) != null) {
                ResultUtil.error(ErrorType.UserExits)
            } else if (userService.selectUserByName(newUser.userName) != null) {
                ResultUtil.error(ErrorType.UserExits)
            } else {
                val user = userService.selectUserByName(userName)
                val passWord = passwordEncode.encode(newUser.password)
                newUser.password = passWord!!
                newUser.createTime = Date()
                newUser.lastLoginTime = Date()
                newUser.updateUser = user?.id!!
                newUser.updateTime = Date()
                userService.insert(newUser)
                ResultUtil.success()
            }
        } catch (e: Exception) {
            logger.error(e.toString())
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @PostMapping(value = ["api/deleteUserById"])
    @ResponseBody
    fun deleteUserById(@RequestParam id: Int): RequestResult<*> {
        return try {
            userService.deleteById(id)
            ResultUtil.success()
        } catch (e: Exception) {
            logger.error(e.toString())
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @PostMapping(value = ["api/updateUser"])
    @ResponseBody
    fun updateUser(@RequestBody newUser: PersonUser, @RequestParam userName: String): RequestResult<*> {
        return try {
            if (userService.selectUserByAccount(newUser.account) != null) {
                ResultUtil.error(ErrorType.UserExits)
            } else if (userService.selectUserByName(newUser.userName) != null) {
                ResultUtil.error(ErrorType.UserExits)
            } else {
                val user = userService.selectUserByName(userName)
                val passWord = passwordEncode.encode(newUser.password)
                newUser.password = passWord!!
                newUser.updateUser = user?.id!!
                newUser.updateTime = Date()
                userService.update(newUser)
                ResultUtil.success()
            }
        } catch (e: Exception) {
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @PostMapping(value = ["api/queryUser"])
    @ResponseBody
    fun queryUser(): RequestResult<*> {
        return try {
            ResultUtil.success(userService.queryAll())
        } catch (e: Exception) {
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @GetMapping(value = ["api/selectTotalUser"])
    @ResponseBody
    fun selectTotalUser(): RequestResult<*> {
        return try {
            ResultUtil.success(userService.selectTotalUser())
        } catch (e: Exception) {
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @GetMapping(value = ["api/queryAllUserByLimit"])
    @ResponseBody
    fun queryAllByLimit(@RequestParam pageNow: Int, @RequestParam pageSize: Int): RequestResult<*> {
        return try {
            ResultUtil.success(userService.queryAllByLimit(pageNow, pageSize))
        } catch (e: Exception) {
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @GetMapping(value = ["api/getRolesByUser"])
    @ResponseBody
    fun getRolesByUser(@RequestParam userId: Int): RequestResult<*> {
        return try {
            val roles = roleService.selectRolesByUserId(userId)
            ResultUtil.success(roles)
        } catch (e: Exception) {
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @PostMapping(value = ["api/updateState"])
    @ResponseBody
    fun updateState(
        @RequestParam id: Int,
        @RequestParam prop: String,
        @RequestParam userName: String
    ): RequestResult<*> {
        return try {
            val newUser = userService.queryById(id)!!
            when (prop) {
                "enabled" -> newUser.enabled = !newUser.enabled
                "accountNonExpired" -> newUser.accountNonExpired = !newUser.accountNonExpired
                "accountNonLocked" -> newUser.accountNonLocked = !newUser.accountNonLocked
                "credentialsNonExpired" -> newUser.credentialsNonExpired = !newUser.credentialsNonExpired
                else -> {}
            }
            val updateUser = userService.selectUserByName(userName)
            newUser.updateUser = updateUser?.id!!
            newUser.updateTime = Date()
            userService.update(newUser)
            ResultUtil.success()
        } catch (e: Exception) {
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @GetMapping(value = ["api/selectRolesByUserId"])
    @ResponseBody
    fun selectRolesByUserId(@RequestParam userId: Int): RequestResult<*> {
        return try {
            val roles = roleService.selectRolesByUserId(userId)
            ResultUtil.success(roles)
        } catch (e: Exception) {
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }

    @PostMapping(value = ["api/updateUserRoleRelation"])
    @ResponseBody
    fun updateUserRoleRelation(@RequestBody roleIds: String?, @RequestParam userId: Int): RequestResult<*> {
        return try {
            val json = JSON.parseObject(roleIds)
            logger.info(json.toString() + json["roleIds"])
            val list = json["roleIds"] as List<Int>
            if (list.isNotEmpty()) {
                userService.deleteAllUserRoleRelationByUserId(userId)
                for (roleId in list) {
                    userService.addUserRoleRelation(userId, roleId)
                }
            } else {
                logger.error("other")
                return ResultUtil.error(ErrorType.UNKNOWN)
            }
            ResultUtil.success()
        } catch (e: Exception) {
            logger.error(e.toString())
            ResultUtil.error(ErrorType.UNKNOWN)
        }
    }
}